#ifndef EXPERIMENTRUNUI_H
#define EXPERIMENTRUNUI_H

#include <QCategoryAxis>
#include <QChart>
#include <QLineSeries>
#include <QBarSet>
#include <QBarCategoryAxis>
#include <QLineEdit>
#include <QSet>
#include <QSplineSeries>
#include <QMessageBox>
#include <QWidget>
#include <QValueAxis>
#include <QVariant>
#include <QThread>
#include <QAction>
#include <QMenu>
#include <QScrollBar>
#include <QModelIndex>
#include <QToolTip>
#include <QListView>
#include <QBarSeries>
#include <QLabel>
#include <QTableWidget>
#include <QFontMetrics>
#include <QtGlobal>


#include "Constant.h"
#include "Convertion.h"
#include "devicemanagementui.h"
#include "global.h"
#include "InstructionsService.h"
#include "socketclient.h"
#include "pause.h"
#include "ProcedureService.h"
#include "QpcrLog.h"
#include "UiStruct.h"
#include "ExperimentService.h"
#include "custommessagebox.h"

#define MAX_BAR_LABEL_FONT 10 // 柱状图标签最大的字体点大小（pt）（以四个字符为基准）
#define MIN_BAR_LABEL_FONT 6 // 柱状图标签最小的字体点大小（pt）（以四个字符为基准）

QT_CHARTS_USE_NAMESPACE

namespace Ui {
class ExperimentRunUi;
}

class ExperimentRunUi : public QWidget
{
    Q_OBJECT

public:
    explicit ExperimentRunUi(QWidget *parent = nullptr);
    ~ExperimentRunUi();

public:
    Ui::ExperimentRunUi *ui;

signals:
    void clearResultCurve();
    void experimentFinished();
    void nextEvent();
    void previousEvent();
    void successRenderResultCurve();
    void updateInactiveDeviceList();
    void sigInitStyle(); // 刚进入循环时，界面样式设置
    void sigIsEmptyStyle(QString text); // 回传信息为空时，界面样式设置
    void sigIsErrorStyle(QStringList guzhangData); // 回传信息为故障时，界面样式设置
    void sigIsSuccessStyle(); // 回传信息为成功时，界面样式设置
    void sigIsTempStyle(QString wenduData); // 回传温度时，界面样式设置
    void sigRenderStage(QString stageNo); // 渲染阶段
    void sigMinusTime(); // 回传数据，减时间和增加步骤/阶段/循环数
    void sigGetWenduData(); // 温度回传数据
    void sigGetYingGuangData(); // 荧光回传数据
    void sigGetGuzhangData(); // 故障回传数据
    void sigCloseDeviceSocket(); // 关闭Socket通信
    void sigGetFinishedProcedureTime(); // 获取已完成的扩增信息
    void sigGetZeroSuccess(); // 获取当实验结束回传0时信号

    void sigRenderZhiLingInfo(); // 渲染指令信息

    void startSaveExperimentInfo(); // 开始实验，保存信息
    void renderRestoreList(); // 渲染实验恢复列表

    void sigShowRunningStatus(QString status); // 渲染运行状态颜色到tab页上

    void sigCurveLabelFilter(QString filterNum, QString filterType); // 曲线过滤函数（图标过滤）信号函数

public slots:
    void expStartRunning();
    void expPauseRunning();
    void expStopRunning();
    void nextCallback();
    void expRunningTimerCallback();

    void callbackInitStyle(); // 刚进入循环时，界面样式设置
    void callbackIsEmptyStyle(QString text); // 回传信息为空时，界面样式设置
    void callbackIsErrorStyle(QStringList guzhangData); // 回传信息为故障时，界面样式设置
    void callbackIsSuccessStyle(); // 回传信息为成功时，界面样式设置
    void callbackIsTempStyle(QString wenduData); // 回传温度时，界面样式设置
    void callbackRenderStage(QString stageNo); // 渲染阶段
    void callbackMinusTime(); // 回传数据，减时间和增加步骤/阶段/循环数
    void callbackGetWenduData(); // 温度回传数据
    void callbackGetYingGuangData(); // 荧光回传数据
    void callbackGetGuzhangData(); // 故障回传数据
    void callbackCloseDeviceSocket(); // 关闭Socket通信
    void callbackGetFinishedProcedureTime(); // 获取已完成的扩增信息

    void callbackGetZeroSuccess(); // 获取当实验结束回传0时槽


    void callbackRenderNotParseZhilingInfo(); // 渲染未解析的指令信息

    void runningTimerCallback(); // 运行时间计时器

    void curveLabelFilter(QString filterNum, QString filterType); // 曲线过滤函数（图标过滤）

    void ShowTooltip(QModelIndex index);

public:
    QHash<QString, QString> sendRuntimeData();
    void allComponentsInvalid();
    void allComponentsValid();
    void callbackRenderZhiLingInfo(); // 渲染指令信息
    void changeCurrentActiveDevice(int index);
    //    void getRunTimeData(QString id, ReactionPlate reactionPlate, int totalCycling, Experiment experiment, int volumn, int procedureStepCount, int procedureStageCount, ExperimentService *experimentService, int totalrunningTime);
    void getRunTimeData();
    void renderRunWlkData(QHash<QString, QString> wlkRunData);
    void RenderTableRowColumnFromXML();
    QHash<QString, QString> getReactionPlateTarget();
    QHash<QString, QString> returnPageInfos();

public:
    ConnectedDeviceStruct cDevS;
    QList<QList<QHash<QString, QString>>> saveYingguangDataList;
    QLineEdit *comboboxEdit;
    bool runFlag;
    ReactionPlate reactionPlate;

public:
    Convertion *convertion;
    CustomMessageBox *cusMsg;
    Experiment experiment;
    ExperimentService *experimentService;
    int currentCycling;
    int currentProcedureStepCount;
    QList<float> previousStepTimeAndTemp;
    QList<float> nextStepTimeAndTemp;
    int procedureStepCount;
    int procedureStageCount;
    int runningMinute;
    int runningSecond;
    int timerFlag;
    int setSize;
    int symbolFlag;
    int totalCycling;
    int totalrunningTime;
    int saveTotalrunningTime;
    int xAxisMaximum;
    int yAxisMaximum;
    int volumn;
    pause *pauseDialog;
    ProcedureService *procedureService;
    QAction *action_1;
    QAction *action_2;
    QAction *action_3;

    QChart *expRunChart; // 荧光曲线
    QChart *expBarChart; // 荧光柱状图

    QHash<QHash<QString,QString>,QList<QHash<QString,QString>>> procedureList;
    QHash<QString, QString> targetLegend;
    QList<QSplineSeries*> cy5SeriesList;
    QList<QSplineSeries*> famSeriesList;
    QList<QSplineSeries*> roxSeriesList;
    QList<QSplineSeries*> vicSeriesList;
    QList<QString> zhilingList;
    QList<YingGuang> yingguangDataList;
    QList<YingGuang> saveYingguangList;
    QList<QHash<QString, QString>> yingguangData;
    QMenu *menu;
    qreal xSeries;
    QSet<QString> currentYinggangSymbolDataSet;
    QString currentYinggangSymbolData;
    QString id;
    QString pauseTemperature;
    QString previousStage;
    QString previousNo;
    QString previousStep;
    QString previousCycling;
    QString targetLegendColor1;
    QString targetLegendColor2;
    QString targetLegendColor3;
    QString targetLegendColor4;
    QString targetReporter1;
    QString targetReporter2;
    QString targetReporter3;
    QString targetReporter4;
    QString wenduDataFlag;
    QString wenduData;
    QStringList wenduDataList;
    QTimer *expStartRunningTimer;
    QTimer *runningTimer;
    QThread *runThread;

    /* 记录选中的靶基因图例 */
    // 曲线图例
    bool cy5Visible;
    bool famVisible;
    bool vicVisible;
    bool roxVisible;
    // 柱状图图例
    QString curBarVisible;
    // 存储柱状图图例
    QHash<QString, bool> lineVisibleList;

    /* 坐标轴 */
    QCategoryAxis *expRunXAxis; // 曲线横坐标轴
    QValueAxis *expRunYAxis; // 曲线纵坐标轴

    QBarCategoryAxis *expBarXAxis; // 柱状图横坐标轴
    QValueAxis *expBarYAxis; // 柱状图纵坐标轴

    QBarSet *barSet; // 柱状图组
    QBarSeries *barSeries; // 柱状图系列
    int barSetCount; // 柱状图组数量


    QModelIndex normalIndex;

private:
    bool reactionPlateDataIsEmpty();
    QStringList procedureCallback(ConnectedDeviceStruct, QString);
    QStringList reactionPlateCallback(ConnectedDeviceStruct, QString);
    void experimentRunning();
    void reactionPlateToRunning();
    void renderRunTimeInfo();
    void renderRunningCurve(QList<QHash<QString, QString>>);
    QColor stringToColor(QString colorStr);
    void updateTable();
    void sleep(int);

    void createLineChart(); // 创建曲线图表
    void createBarChart(); // 创建柱状图图表

    void renderBarXAxisData(); // 根据反应板孔位选择，渲染横轴数据
    void renderBarData(QList<QHash<QString, QString>> yingguangData); // 根据当前荧光曲线数据，设置柱状图数据

    void renderLegendStyle(); // 渲染图例样式

    void renderLineDataStyle(); // 渲染扩增曲线数据样式
    void renderBarDataStyle(); // 渲染柱状图数据样式

    void colorControlFunction(); // 颜色显示器控制函数

    QString initBarLegendStyle(); // 初始化柱状图图例颜色

};

#endif // EXPERIMENTRUNUI_H
